x86/nmi: start NMI watchdog on CPU0 after SMP bootstrap
authorIgor Druzhinin <igor.druzhinin@citrix.com>
Tue, 20 Feb 2018 09:16:56 +0000 (10:16 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 20 Feb 2018 09:16:56 +0000 (10:16 +0100)
commita44f1697968e04fcc6145e3bd51c748b57047240
treebab253dd452fa2f8907ee29632364b63f80c8b62
parent682b13c259e531f6848f535032c256ec8fcaca71
x86/nmi: start NMI watchdog on CPU0 after SMP bootstrap

We're noticing a reproducible system boot hang on certain
Skylake platforms where the BIOS is configured in legacy
boot mode with x2APIC disabled. The system stalls immediately
after writing the first SMP initialization sequence into APIC ICR.

The cause of the problem is watchdog NMI handler execution -
somewhere near the end of NMI handling (after it's already
rescheduled the next NMI) it tries to access IO port 0x61
to get the actual NMI reason on CPU0. Unfortunately, this
port is emulated by BIOS using SMIs and this emulation for
some reason takes more time than we expect during INIT-SIPI-SIPI
sequence. As the result, the system is constantly moving between
NMI and SMI handler and not making any progress.

To avoid this, initialize the watchdog after SMP bootstrap on
CPU0 and, additionally, protect the NMI handler by moving
IO port access before NMI re-scheduling. The latter should also
help in case of post boot CPU onlining. Although we're running
watchdog at much lower frequency at this point, it's neveretheless
possible we may trigger the issue anyway.

Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/apic.c
xen/arch/x86/smpboot.c
xen/arch/x86/traps.c